package com.zsd.android.arouter_api;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.LruCache;

import com.zsd.android.annotation.model.RouterBean;

import java.util.Map;

public class RouterManager {

    //APT生成文件前缀名（包名拼接）
    private static final String GROUP_FILE_PREFIX_NAME = ".ARouter$$Group$$";
    private static final String PATH_FILE_PREFIX_NAME = ".ARouter$$Path$$";

    private static volatile RouterManager instance;

    //路由的组名
    private String group;
    //路由Path路径
    private String path;
    //Lru缓存，key：组名，value：路由组Group加载接口
    private LruCache<String, ARouterLoadGroup> groupLruCache;
    //Lru缓存，key：路径名，value：路由Path路径加载接口
    private LruCache<String, ARouterLoadPath> pathLruCache;

    private RouterManager() {
        groupLruCache = new LruCache<>(163);
        pathLruCache = new LruCache<>(163);
    }

    public static RouterManager getInstance() {
        RouterManager manager = instance;
        if (manager == null) {
            synchronized (RouterManager.class) {
                if (manager == null) {
                    manager = new RouterManager();
                    instance = manager;
                }
            }
        }
        return manager;
    }

    //传递路由的地址
    public BundleManager build(String path) {
        if (TextUtils.isEmpty(path) || !path.startsWith("/")) {
            throw new IllegalArgumentException("未按照规范配置，如：/app/MainActivity");
        }
        group = subFromPath2Group(path);
        this.path = path;
        return new BundleManager();
    }

    private String subFromPath2Group(String path) {
        if (path.lastIndexOf("/") == 0) {
            //只有一个 / 的情况
            throw new IllegalArgumentException("未按照规范配置，如：/app/MainActivity");
        }
        String finalGroup = path.substring(1, path.indexOf("/", 1));
        if (TextUtils.isEmpty(finalGroup)) {
            throw new IllegalArgumentException("未按照规范配置，如：/app/MainActivity");
        }
        return finalGroup;
    }

    /**
     * 开始跳转
     *
     * @param mContext 上下文
     * @param bundleManager 参数管理
     * @param code 可能是resultCode，也可能是requestCode。取决于isResult
     * @return 普通的跳转可以忽略，用于跨模块CALL接口
     */
    public Object navigation(Context mContext, BundleManager bundleManager, int code) {
        String groupClassName = mContext.getPackageName() + ".apt" + GROUP_FILE_PREFIX_NAME + group;

        //读取路由组Group类文件（缓存，懒加载）
        ARouterLoadGroup groupLoad = groupLruCache.get(group);
        try {
            if (groupLoad == null) {
                //加载APT路由组Group类文件
                Class<?> clazz = Class.forName(groupClassName);
                //初始化类文件
                groupLoad = (ARouterLoadGroup) clazz.newInstance();
                groupLruCache.put(group, groupLoad);
            }

            Map<String, Class<? extends ARouterLoadPath>> groupMap = groupLoad.loadGroup();
            if (groupMap.isEmpty()) {
                throw new RuntimeException("路由表Group加载失败！");
            }

            //读取路由Path路径类文件缓存（缓存，懒加载）
            ARouterLoadPath pathLoad = pathLruCache.get(path);
            if (pathLoad == null) {
                //通过组Group加载接口，获取Path加载接口
                Class<? extends ARouterLoadPath> clazz = groupMap.get(group);
                if (clazz != null) {
                    //初始化类文件
                    pathLoad = clazz.newInstance();
                }
                if (pathLoad != null) {
                    pathLruCache.put(path, pathLoad);
                }
            }
            if (pathLoad != null) {
                Map<String, RouterBean> pathMap = pathLoad.loadPath();
                if (pathMap.isEmpty()) {
                    throw new RuntimeException("路由表Path加载失败！");
                }
                RouterBean routerBean = pathMap.get(path);
                if (routerBean != null) {
                    //类型判断，方便拓展
                    switch (routerBean.getType()) {
                        case ACTIVITY:
                            Intent intent = new Intent(mContext, routerBean.getClazz());
                            Bundle bundle = bundleManager.getBundle();
                            intent.putExtras(bundle);

                            //注意： startActivity --> setResult
                            if (bundleManager.isResult()) {
                                ((Activity) mContext).setResult(code, intent);
                                ((Activity) mContext).finish();
                            }
                            if (code > 0) {
                                //跳转需要回调
                                ((Activity) mContext).startActivityForResult(intent, code);
                            } else {
                                mContext.startActivity(intent);
                            }
                            break;

                        case CALL:
                            //返回接口的实现类
                            return routerBean.getClazz().newInstance();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
